package com.xhwl.data.aop;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xhwl.common.annotation.OrganizationModel;
import com.xhwl.common.enums.OperationTypeEnum;
import com.xhwl.common.exception.DataException;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.sdata.Organization;
import com.xhwl.data.pojo.annotation.OrganizationHandle;
import com.xhwl.data.service.IOrganizationService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Author: luyi
 * @Description:
 * @Date: Create in 17:41 2021/5/10
 */
@Aspect
@Component
public class OrganizationAspect {


    public static final Logger log = LoggerFactory.getLogger(OrganizationAspect.class);

    @Autowired
    private IOrganizationService organizationService;

    @Pointcut("@annotation(com.xhwl.data.pojo.annotation.OrganizationHandle)")
    public void organization(){}

    /**
     * 切点检查-组织合法性校验
     * @param joinPoint
     */
    @Before("organization()()")
    public void before(JoinPoint joinPoint){
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        OrganizationHandle annotation = signature.getMethod().getAnnotation(OrganizationHandle.class);
        if(OperationTypeEnum.CREATE == annotation.operationType()){
            Object[] args = joinPoint.getArgs();
            Object arg = args[0];
            OrganizationModel annotation1 = arg.getClass().getAnnotation(OrganizationModel.class);
            if(null == annotation1){
                log.error("创建组织未识别到organization注解");
                return;
            }
            String str = JSONObject.toJSONString(arg);
            JSONObject jsonObject = JSON.parseObject(str);
            Organization organization = new Organization();
            // 组织表里统一不保存code信息（暂时没有必要）
//            organization.setCode((String) jsonObject.get("code"));
            organization.setName((String) jsonObject.get("name"));
            organization.setParentId((Integer) jsonObject.get("parentId"));
            organization.setType(annotation1.type().id.intValue());
            organization.setSortField(jsonObject.getInteger("sortField"));

            Organization parent = organizationService.getById(organization.getParentId());
            if(null == parent){
                log.error("组织创建失败， 上级id不存在");
                throw new DataException("创建失败，上级id组织不存在");
            }
            organization.setParentId(parent.getId());
            if(null != parent.getProjectId()){
                organization.setProjectId(parent.getProjectId());
            }
            organization.setLevel(parent.getLevel() + 1);
            organization.setIsDeleted(false);
            organization.setIndustryId(parent.getIndustryId());
            organization.setEnterpriseId(parent.getEnterpriseId());
            ResultJson resultJson = organizationService.create(organization);
            if(!resultJson.getState()){
                log.error("创建组织失败 {} ", resultJson.getMessage());
                throw new DataException(resultJson.getMessage());
            }
            //组织id回写
            Class<?> aClass = arg.getClass();
            Field[] declaredFields = getAllFields(aClass);
            try {
                int i = 0;
                for (Field declaredField : declaredFields) {
                    if(2 == i){
                        break;
                    }
                    if("organizationId".equals(declaredField.getName())){
                        declaredField.setAccessible(true);
                        Integer organizationId = organization.getId();
                        declaredField.set(arg, organizationId);
                        i ++;
                    } else if("enterpriseId".equals(declaredField.getName())){
                        declaredField.setAccessible(true);
                        Integer enterpriseId = organization.getEnterpriseId();
                        declaredField.set(arg, enterpriseId);
                        i ++;
                    }
                }
            } catch (Exception e){
                e.printStackTrace();
            }

            String str1 = JSONObject.toJSONString(arg);
            JSONObject jsonObject1 = JSON.parseObject(str1);
            if(null == jsonObject1.get("organizationId")){
                throw new DataException("缺少组织id");
            }
        }
    }

    private static Field[] getAllFields(Class<?> clazz) {
        List<Field> fieldList = new ArrayList<>();
        while (clazz != null){
            fieldList.addAll(Arrays.asList(clazz.getDeclaredFields()));
            clazz = clazz.getSuperclass();
        }
        Field[] fields = new Field[fieldList.size()];
        return fieldList.toArray(fields);
    }
}
